package org.oncase.smcase.util;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import org.hibernate.Transaction;

public class TransactionalContext implements InvocationHandler {
	
	private Object target;
	
	public TransactionalContext(Object target) {
		this.target = target;
	}

	public static Object newInstance(Object obj) {
		return Proxy.newProxyInstance(
				obj.getClass().getClassLoader(),
                obj.getClass().getInterfaces(),
                new TransactionalContext(obj));
	}
	
	@Override
	public Object invoke(Object obj, Method method, Object[] args)
			throws Throwable {
		Transaction transaction = HibernateUtils.currentSession().getTransaction();

		try {
			transaction.begin();
			Object result = method.invoke(this.target, args);
			transaction.commit();
			return result;

		} catch (InvocationTargetException e) {
			transaction.rollback();
			throw e.getCause();

		} catch (Exception e) {
			transaction.rollback();
			throw e;

		}
	}

}
